package com.ddwl.order.service;

import com.alibaba.fastjson.JSON;
import com.ddwl.common.constant.OrderEnum;
import com.ddwl.common.constant.RabbitMqConstants;
import com.ddwl.common.constant.StatisticsEnum;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.*;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.order.dao.*;
import com.ddwl.order.dao.model.*;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.funds.OrderRefundCreBo;
import com.ddwl.schema.bo.gate.DingTalkBo;
import com.ddwl.schema.bo.goods.SupplierBo;
import com.ddwl.schema.bo.order.*;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.base.RestVo;
import com.ddwl.schema.vo.funds.OrderRefundsVo;
import com.ddwl.schema.vo.goods.SupplierVo;
import com.ddwl.schema.vo.order.*;
import com.ddwl.schema.vo.shop.ShopVo;
import com.ddwl.schema.vo.user.UserVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.util.StringUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 售后订单处理
 *
 * @author wenbin
 */
@Service
@RefreshScope
@Slf4j
public class AfterSaleOrderServer {


    @Resource
    private OrderInfoDao orderInfoDao;
    @Resource
    private AfterSaleOrderDao afterSaleOrderDao;
    @Resource
    private OrderAddressServer orderAddressServer;
    @Resource
    private OrderPayServer orderPayServer;
    @Resource
    private OrderSpuDao orderSpuDao;
    @Resource
    private OrderAddrDao orderAddrDao;
    @Resource
    private OrderPayDao orderPayDao;
    @Resource
    private FundsApi fundsApi;
    @Resource
    private WalletApi walletApi;
    @Resource
    private GoodsApi goodsApi;
    @Resource
    private ShopApi shopApi;
    @Resource
    private UserApi userApi;

    //售后单过期时间
    @Value("${ddwl.order.after_sale_expired_time}")
    private Integer afterSaleExpiredTime;
    @Resource
    private RabbitTemplate rabbitTemplate;


    @Transactional(rollbackFor = Throwable.class)
    public String create(CreateAfterSaleOrderBo bo, String userId, String userName) {
        OrderSpu spu = orderSpuDao.selectByPrimaryKey(bo.getSpuOrderId());
        ParamException.isTrue(spu == null, "订单[" + bo.getSpuOrderId() + "]不存在");

        //判断退款金额不能超过总付款金额
        AfterSaleOrder afterSaleOrder = new AfterSaleOrder();
        afterSaleOrder.setSpuOrderId(spu.getId());
        List<AfterSaleOrder> afterSaleOrderList = afterSaleOrderDao.select(afterSaleOrder);
        if (afterSaleOrderList != null && afterSaleOrderList.size() != 0) {
            ParamException.isTrue((afterSaleOrderList.stream().filter(o -> o.getAfterSaleStatus() == 6).map(o -> o.getAfterSaleAmount())
                    .reduce(BigDecimal.ZERO, BigDecimal::add))
                    .add(bo.getAfterSaleAmount()).compareTo(spu.getRealPrice().multiply(new BigDecimal(spu.getSkuQty()))) > 0, "退款金额不能大于实际付款金额");
            ParamException.isTrue((afterSaleOrderList.stream().filter(o -> o.getAfterSaleStatus() == 6 && o.getSkuQty() != null).mapToInt(AfterSaleOrder::getSkuQty).sum()) + (bo.getSkuQty() == null ? 0 : bo.getSkuQty()) > spu.getSkuQty(), "退货数量不能大于实际购买数量");
            for (AfterSaleOrder o : afterSaleOrderList) {
                ParamException.isTrue(o.getAfterSaleStatus() >= 1 && o.getAfterSaleStatus() <= 5, "有一个申请在处理中,请联系客服");
            }
        }
        //判断是否已经过售后保质期
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(spu.getOrderId());
        OrderInfo orderInfo2 = orderInfoDao.selectOne(orderInfo);
        ParamException.isTrue(orderInfo2 != null && orderInfo2.getRepairTime() != null && orderInfo2.getRepairTime().compareTo(Instant.now()) < 0, "已过保修期,不能退换货,如有问题,联系客服");
        ParamException.isTrue(orderInfo2 != null && OrderEnum.OrderStatus.UN_PAY.getCode().equals(orderInfo2.getStatus()), "订单未支付,不能退款");
        ParamException.isTrue(orderInfo2 != null && orderInfo2.getStatus() >= OrderEnum.OrderStatus.SEND.getCode() && OrderEnum.AfterType.REFUND.getCode().equals(bo.getAfterSaleType()), "只有未发货的订单可以申请仅退款");
        ParamException.isTrue((orderInfo2 != null && orderInfo2.getStatus() >= OrderEnum.OrderStatus.CANCEL.getCode() || orderInfo2 != null && OrderEnum.OrderStatus.UN_PAY.getCode().equals(orderInfo2.getStatus())) && bo.getAfterSaleType() <= 3, "当前状态不可以申请售后");

        AfterSaleOrder entity = BeanConverUtils.convertBean(bo, AfterSaleOrder.class);
        if (bo.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())) {
            OrderAddrVo orderAddr = orderAddressServer.getOrderAddr(orderInfo2.getId());
            entity.setReSendAddr(orderAddr.getAddress());
            entity.setReSendRegion(orderAddr.getRegionId());
            entity.setReSendReceiver(orderAddr.getReceiver());
            entity.setReSendTel(orderAddr.getMobile());
        }
        entity.setSpuOrderId(spu.getId());
        entity.setOrderId(spu.getOrderId());
        entity.setSkuSnapshoot(JSON.toJSONString(spu));
        entity.setSkuId(spu.getId());
        entity.setUserId(userId);
        entity.setUserName(userName);
        entity.setAfterSaleStatus(OrderEnum.AfterStatus.APPLY.getCode());
        entity.setId(UUIDGenerator.getTimeUUID());
        entity.setPlatformTag(0);
        if (OrderEnum.AfterType.REFUND.getCode().equals(entity.getAfterSaleType())) {
            OrderSpu orderSpu = orderSpuDao.selectByPrimaryKey(entity.getSpuOrderId());
            if (orderSpu == null) {
                entity.setSkuQty(0);
            } else {
                entity.setSkuQty(orderSpu.getSkuQty());
            }
        }
        afterSaleOrderDao.insert(entity);
        //更新原零售单售后状态
        updateOrderInfoAfterStatus(orderInfo2.getId(), entity.getSpuOrderId());
        //如果发生退款更新佣金
        if (OrderEnum.AfterType.REFUND.getCode().equals(entity.getAfterSaleType()) ||
                OrderEnum.AfterType.RETURN.getCode().equals(entity.getAfterSaleType())) {
            walletApi.createOrderRefundAmount(entity.getOrderId(), entity.getSpuOrderId(), entity.getAfterSaleAmount(), entity.getId(), entity.getSkuQty());
        }
        //发送钉钉消息
        DingTalkBo bo1 = new DingTalkBo();
        bo1.setMessage("");
        bo1.setChannel(StatisticsEnum.channel.PENDING_AFTERSALE_COUNT.getId());
        rabbitTemplate.convertAndSend(RabbitMqConstants.DINGDING_TALK_MESSAGE, JSON.toJSONString(bo1));
        return entity.getId();
    }


    /**
     * 更新订单售后状态
     */
    public void updateOrderInfoAfterStatus(String orderId, String spuId) {
/*        OrderInfo info = orderInfoDao.selectByPrimaryKey(orderId);
        ParamException.isTrue(info==null,"订单不存在");
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.setId(orderId);
        orderInfo.setAfterSaleCount((orderInfo.getAfterSaleCount()==null?0:orderInfo.getAfterSaleCount())+1);
        orderInfo.setIsAfterSale(1);
        orderInfoDao.updateByPrimaryKeySelective(orderInfo);*/

        OrderSpu orderSpu = orderSpuDao.selectByPrimaryKey(spuId);
        ParamException.isTrue(orderSpu == null, "订单不存在");
        OrderSpu spu = new OrderSpu();
        spu.setId(spuId);
        spu.setAfterSaleCount(orderSpu.getAfterSaleCount() == null ? 0 : orderSpu.getAfterSaleCount() + 1);
        spu.setIsAfterSale(OrderEnum.AfterStatus.APPLY.getCode());
        orderSpuDao.updateByPrimaryKeySelective(spu);

        upSkuSnapshoot(orderId);

    }

    /**
     * 更新快照售后状态
     */
    private void upSkuSnapshoot(String orderId) {
        if (StringUtil.isEmpty(orderId)) {
            return;
        }
        OrderSpu sp = new OrderSpu();
        sp.setOrderId(orderId);
        List<OrderSpu> orderSpus = orderSpuDao.select(sp);
        if (!CollectionUtils.isEmpty(orderSpus)) {
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setId(orderId);
            orderInfo.setSkuSnapshoot(JSON.toJSONString(orderSpus));
            orderInfoDao.updateByPrimaryKeySelective(orderInfo);
        }
    }

    /**
     * 用户取消订单
     *
     * @param bo
     * @param userId
     * @return
     */

    public void cancelAfterSaleOrder(ConfirmAfterSaleBo bo, String userId) {
        String afterId = bo.getAfterId();
        if (StringUtils.hasText(bo.getSpuOrderId())) {
            bo.setUserId(userId);
            List<Integer> list = new ArrayList<>();
            list.add(OrderEnum.AfterStatus.ACCEPT.getCode());
            list.add(OrderEnum.AfterStatus.APPLY.getCode());
            AfterSaleOrder afterSaleOrder1 = afterSaleOrderDao.queryAfterSaleOrder(bo, list);
            ParamException.isNull(afterSaleOrder1, "当前状态不支持取消,请联系客服");
            afterId = afterSaleOrder1.getId();
        }
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(afterId);
        //OrderInfo orderInfo = orderInfoDao.selectByPrimaryKey(afterSaleOrder.getOrderId());
        //ParamException.isTrue(orderInfo==null,"原订单不存在");
        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() >= 3,
                "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不支持取消,请联系客服");
        afterSaleOrderDao.closed(afterId, userId);
        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        orderSpu.setIsAfterSale(0);
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);
        upSkuSnapshoot(afterSaleOrder.getOrderId());
        //如果发生退款更新佣金
        if (OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType()) ||
                OrderEnum.AfterType.RETURN.getCode().equals(afterSaleOrder.getAfterSaleType())) {
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
        }
    }


    /**
     * 更新售后商品的售后状态
     *
     * @param afterSaleOrder
     */
    private void updateOrderSpuAfterSaleStatus(AfterSaleOrder afterSaleOrder) {
        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        List<AfterSaleOrder> afterSaleOrders = afterSaleOrderDao.queryOrderSpuAfterSale(afterSaleOrder.getSpuOrderId());
        if (CollectionUtils.isEmpty(afterSaleOrders)) {
            orderSpu.setIsAfterSale(0);
        } else {
            orderSpu.setIsAfterSale(2);
        }
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);

        OrderSpu spu = orderSpuDao.selectByPrimaryKey(afterSaleOrder.getSpuOrderId());
        upSkuSnapshoot(spu.getOrderId());
    }


    /**
     * 拒绝用户售后单据
     *
     * @param bo
     * @return
     */
    public void rejectAfterSaleOrder(ConfirmAfterSaleBo bo) {
        ParamException.isBlank(bo.getAfterId(), "售后单号为空");
        ParamException.isBlank(bo.getRejectReason(), "拒绝原因为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(bo.getAfterId());
        ParamException.isNull(afterSaleOrder, "售后单不存在");
        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() >= 4,
                "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不支持拒绝");
        afterSaleOrderDao.reject(bo.getAfterId(), bo.getRejectReason());
        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        orderSpu.setIsAfterSale(0);
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);
        upSkuSnapshoot(afterSaleOrder.getOrderId());
        //如果发生退款更新佣金
        if (OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType()) ||
                OrderEnum.AfterType.RETURN.getCode().equals(afterSaleOrder.getAfterSaleType())) {
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
        }
    }


    /**
     * 分页查询订单包含商品信息
     *
     * @param pageBo
     * @return
     */
    public PageVo<AfterSaleOrderVo> getPage(PageBo<QueryAfterSaleOrderListBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        PageInfo<AfterSaleOrder> info = new PageInfo(afterSaleOrderDao.queryAfterSaleOrderList(pageBo.getParam()));
        List<AfterSaleOrder> orders = info.getList();
        if (CollectionUtils.isEmpty(orders)) {
            return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), new ArrayList<>());
        }
        Set<String> userIds = orders.stream().map(AfterSaleOrder::getUserId).collect(Collectors.toSet());
        List<UserVo> users = userApi.getUserByIds(userIds).getResult();
        Map<String, UserVo> userMap = users.stream().collect(Collectors.toMap(UserVo::getId, Function.identity()));
        List<AfterSaleOrderVo> list = orders.stream().map(order -> {
            AfterSaleOrderVo vo = BeanConverUtils.convertBean(order, AfterSaleOrderVo.class);
            vo.setUser(userMap.get(vo.getUserId()));
            return vo;
        }).collect(Collectors.toList());
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), list);
    }

    /**
     * 分页查询订单包含商品信息api
     *
     * @param boPageBo
     * @return
     */
    public PageVo<AfterSaleOrderVo> getApiPage(PageBo<QueryAfterSaleOrderListApiBo> boPageBo) {
        PageHelper.startPage(boPageBo.getPage(), boPageBo.getPageSize(), MySqlUtil.orderBy(boPageBo.getSort(), boPageBo.isAsc()));

        QueryAfterSaleOrderListApiBo bo = boPageBo.getParam();
        ParamException.isTrue(bo.getAppId() == null, "appID为空");
        ParamException.isTrue(bo.getTimestamp() == null, "请求时间为空");
        SupplierBo supplierBo = new SupplierBo();
        supplierBo.setAppId(bo.getAppId());
        RestVo<PageVo<SupplierVo>> pageVoRestVo = goodsApi.querySupplierCategory(supplierBo);
        List<SupplierVo> data = pageVoRestVo.getResult().getData();
        ParamException.isTrue(data == null || data.size() == 0, "appID不存在");
        List<String> supplierList = data.stream().map(supplierVo -> {
            return supplierVo.getId();
        }).collect(Collectors.toList());
        bo.setSupplierList(supplierList);
        PageInfo<AfterSaleOrder> info = new PageInfo(afterSaleOrderDao.queryAfterSaleOrderApiList(boPageBo.getParam()));
        List<AfterSaleOrderVo> list = BeanConverUtils.convertBeanList(info.getList(), AfterSaleOrderVo.class);
        return new PageVo<>(info.getTotal(), boPageBo.getPage(), boPageBo.getPageSize(), list);
    }


    /**
     * 用户更新售后物流信息
     *
     * @param bo
     * @return
     */
    public void updateAfterSale(UpdateAfterSaleOrderBo bo, String userId) {
        String afterId = bo.getAfterId();
        if (StringUtils.hasText(bo.getSpuOrderId())) {
            ConfirmAfterSaleBo confirmAfterSaleBo = new ConfirmAfterSaleBo();
            confirmAfterSaleBo.setUserId(userId);
            confirmAfterSaleBo.setSpuOrderId(bo.getSpuOrderId());
            List<Integer> list = new ArrayList<>();
            list.add(OrderEnum.AfterStatus.ACCEPT.getCode());
            AfterSaleOrder afterSaleOrder1 = afterSaleOrderDao.queryAfterSaleOrder(confirmAfterSaleBo, list);
            ParamException.isNull(afterSaleOrder1, "当前状态不支持更新,请联系客服");
            afterId = afterSaleOrder1.getId();
        }
        ParamException.isBlank(afterId, "售后单号为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        if (StringUtils.hasText(userId)) {
            ParamException.isFalse(userId.equals(afterSaleOrder.getUserId()));
        }
        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.ACCEPT.getCode(),
                "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不可以填写物流信息");
        bo.setAfterId(afterId);
        afterSaleOrderDao.updateAfter(bo);

    }

    /**
     * 后台审批订单
     *
     * @param bo
     * @return
     */
    public void confirmAfterSale(ConfirmAfterSaleBo bo) {
        ParamException.isBlank(bo.getAfterId(), "售后单号为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(bo.getAfterId());
        ParamException.isNull(afterSaleOrder);
        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.APPLY.getCode()
                        && afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.REJECT.getCode() && afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.RECEIVED.getCode(),
                "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不可以填写收货信息");
        afterSaleOrderDao.confirmAfter(bo, afterSaleOrder.getAfterSaleStatus(), afterSaleExpiredTime);
        //换货更新零售单位已完成
        if (afterSaleOrder.getAfterSaleStatus() == OrderEnum.AfterStatus.RECEIVED.getCode()) {
/*            OrderInfo order = new OrderInfo();
            order.setId(afterSaleOrder.getOrderId());
            order.setIsAfterSale(2);
            orderInfoDao.updateByPrimaryKeySelective(order);*/

            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(afterSaleOrder.getSpuOrderId());
            orderSpu.setIsAfterSale(2);
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);

            upSkuSnapshoot(afterSaleOrder.getOrderId());
        }

    }

    /**
     * 官方收货
     *
     * @param afterId
     * @return
     */
    public void receivedGood(String afterId) {
        ParamException.isBlank(afterId, "售后单号为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.SEND.getCode(),
                "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不可以进行收货");

        AfterSaleOrder after = new AfterSaleOrder();
        after.setId(afterSaleOrder.getId());
        after.setAfterSaleStatus(OrderEnum.AfterStatus.RECEIVED.getCode());
        afterSaleOrderDao.updateByPrimaryKeySelective(after);
    }


    /**
     * 查询售后订单详细信息
     *
     * @param afterId
     * @return
     */
    public AfterSaleOrderDetailVo getAfterSaleOrderDetail(String afterId) {
        AfterSaleOrderDetailVo afterSaleOrderDetailVo = new AfterSaleOrderDetailVo();
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(afterId);
        afterSaleOrder.setSpu(JSON.parseObject(afterSaleOrder.getSkuSnapshoot(), OrderSpuVo.class));
        AfterSaleOrderVo afterSaleOrderVo = BeanConverUtils.convertBean(afterSaleOrder, AfterSaleOrderVo.class);
        ParamException.isNull(afterSaleOrderVo);
        afterSaleOrderDetailVo.setAfterSaleOrderVo(afterSaleOrderVo);
        afterSaleOrderDetailVo.setOrderInfoVo(getOrderInfoVo(afterSaleOrderVo.getOrderId()));
        afterSaleOrderDetailVo.setOrderAddrVo(orderAddressServer.getOrderAddr(afterSaleOrderVo.getOrderId()));
        afterSaleOrderDetailVo.setOrderPayVo(orderPayServer.getOrderPay(afterSaleOrderVo.getOrderId()));
        return afterSaleOrderDetailVo;
    }


    public OrderInfoVo getOrderInfoVo(String orderId) {
        OrderInfoVo orderInfoVo = BeanConverUtils.convertBean(orderInfoDao.selectByPrimaryKey(orderId), OrderInfoVo.class);
        ParamException.isNull(orderInfoVo);
        return orderInfoVo;
    }


    /**
     * 用户更新售后订单备注
     *
     * @param bo
     * @return
     */

    public void updateRemark(ConfirmAfterSaleBo bo) {
        ParamException.isNull(bo.getAfterId(), "售后订单id不能为空");
        afterSaleOrderDao.updateRemark(bo);
    }

    /**
     * 获取售后原因
     *
     * @return
     */
    public Map<String, String> getAfterReason() {
        Map<String, String> map = new HashMap<>();
        for (OrderEnum.AfterReason t : OrderEnum.AfterReason.values()) {
            map.put(t.getCode().toString(), t.getName());
        }
        return map;
    }

    /**
     * 售后退款
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void refund(String afterId, String userId, String userName) {
        ParamException.isBlank(afterId, "售后单号为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        //退货&&退款判断
        if (afterSaleOrder.getAfterSaleType() == OrderEnum.AfterType.RETURN.getCode()) {
            ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.RECEIVED.getCode() && afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.REFUNDFAIL.getCode(),
                    "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不可以进行退款");
            //退款判断
        } else if (afterSaleOrder.getAfterSaleType() == OrderEnum.AfterType.REFUND.getCode() && afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.REFUNDFAIL.getCode()) {
            ParamException.isTrue(afterSaleOrder.getAfterSaleStatus() != OrderEnum.AfterStatus.APPLY.getCode(),
                    "当前状态" + OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus()) + "不可以进行退款");
        }
        //扣除佣金
        walletApi.submitOrderRefund(afterSaleOrder.getOrderId(), afterSaleOrder.getSpuOrderId(), afterSaleOrder.getAfterSaleAmount(), afterSaleOrder.getId(), afterSaleOrder.getSkuQty());
        //调三方支付
        OrderRefundCreBo creBo = new OrderRefundCreBo();
        creBo.setBizRefundsNo(afterSaleOrder.getId());
        creBo.setOperatorId(userId);
        creBo.setOperatorName(userName);
        OrderPay orderPay = orderPayDao.query(afterSaleOrder.getOrderId());
        ParamException.isNull(orderPay, "付款信息为空");
        creBo.setFundsPayId(orderPay.getFundsPayId());
        creBo.setTradeNo(orderPay.getTradeNo());
        creBo.setOrderId(orderPay.getId());
        creBo.setRefundAmount(afterSaleOrder.getAfterSaleAmount());
        creBo.setNotifyMethod(RabbitMqConstants.AFTER_SALE_REFUND_QUEUE);
        log.info("fundsApi.create param {}", JSON.toJSONString(creBo));
        OrderRefundsVo result = fundsApi.refundsCre(creBo).getResult();
        log.info("fundsApi.create result {}", JSON.toJSONString(result));
        ParamException.isNull(result, "退款失败");
        if (result.getStatus().equals(OrderEnum.PayStatus.FILL.getCode())) {
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
            ParamException.isTrue(true, "退款申请提交失败");
        }
        //ParamException.isTrue(result.getStatus().equals(StatusEnum.FILL.getCode()),"退款申请提交失败");
        //退货&&退款
        if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())) {
            if (result.getStatus().equals(OrderEnum.PayStatus.PRE.getCode()) || result.getStatus().equals(OrderEnum.PayStatus.CRE.getCode())) {
                updateStatus(afterSaleOrder.getId(), OrderEnum.AfterStatus.REFUNDING.getCode());
            }
            if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())) {
                updateStatus(afterSaleOrder.getId(), OrderEnum.AfterStatus.REFUNDED.getCode());
                walletApi.finishOrderRefund(afterSaleOrder.getId());
            }
            //updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDING.getCode());
            //退款
        } else if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())) {
            //updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDING.getCode());
            if (result.getStatus().equals(OrderEnum.PayStatus.PRE.getCode()) || result.getStatus().equals(OrderEnum.PayStatus.CRE.getCode())) {
                updateStatus(afterSaleOrder.getId(), OrderEnum.AfterStatus.REFUNDING.getCode());
            }
            if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())) {
                updateStatus(afterSaleOrder.getId(), OrderEnum.AfterStatus.REFUNDED.getCode());
                walletApi.finishOrderRefund(afterSaleOrder.getId());
            }
        }
        //更新零售订单状态
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(afterSaleOrder.getOrderId());

        OrderSpu orderSpu = new OrderSpu();
        orderSpu.setId(afterSaleOrder.getSpuOrderId());
        if ((result.getStatus().equals(OrderEnum.PayStatus.PRE.getCode()) || result.getStatus().equals(OrderEnum.PayStatus.CRE.getCode())) && afterSaleOrder.getAfterSaleType() == OrderEnum.AfterType.REFUND.getCode()) {
            //orderInfo.setStatus(5);
            orderSpu.setIsAfterSale(OrderEnum.OrderStatus.REFUNDING.getCode());
            orderSpu.setAfterSaleStatus(OrderEnum.OrderStatus.REFUNDING.getCode());
        }
        if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode())) {
            if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())) {
                orderSpu.setIsAfterSale(OrderEnum.OrderStatus.REFUND.getCode());
                orderSpu.setAfterSaleStatus(OrderEnum.OrderStatus.REFUND.getCode());
            } else {
                //校验是否已经退款所有
                Boolean bool = checkAllReturn(afterSaleOrder.getSpuOrderId());
                if (bool) {
                    orderSpu.setIsAfterSale(OrderEnum.OrderStatus.REFUND.getCode());
                    orderSpu.setAfterSaleStatus(OrderEnum.OrderStatus.REFUND.getCode());
                } else {
                    orderSpu.setIsAfterSale(OrderEnum.OrderStatus.SEND.getCode());
                }
            }
            orderInfo.setIsAfterSale(OrderEnum.OrderStatus.SEND.getCode());
            //更新佣金单状态
            walletApi.submitOrderRefund(afterSaleOrder.getOrderId(), afterSaleOrder.getSpuOrderId(), afterSaleOrder.getAfterSaleAmount(), afterSaleOrder.getId(), afterSaleOrder.getSkuQty());
        }
        orderSpuDao.updateByPrimaryKeySelective(orderSpu);

        //更新快照售后信息
        upSkuSnapshoot(afterSaleOrder.getOrderId());

        //全退款零售单更新成已退款
        if (result.getStatus().equals(OrderEnum.PayStatus.SUCCEED.getCode()) && afterSaleOrder.getAfterSaleType() == OrderEnum.AfterType.REFUND.getCode()) {
            OrderSpu spu = new OrderSpu();
            spu.setOrderId(afterSaleOrder.getOrderId());
            List<OrderSpu> spuList = orderSpuDao.select(spu);
            List<OrderSpu> list = spuList.stream().filter(o -> o.getIsAfterSale() == null || o.getIsAfterSale() != 6).collect(Collectors.toList());
            if (list == null || list.size() == 0) {
                orderInfo.setStatus(OrderEnum.OrderStatus.REFUND.getCode());
            }
            Integer check = checkOrderDelivery(afterSaleOrder.getOrderId());
            if ((OrderEnum.OrderStatus.SEND.getCode()).equals(check)) {
                orderInfo.setStatus(OrderEnum.OrderStatus.SEND.getCode());
            }
        }
        orderInfoDao.updateByPrimaryKeySelective(orderInfo);
        if (OrderEnum.OrderStatus.REFUND.getCode().equals(orderInfo.getStatus())) {
            OrderInfo info = orderInfoDao.selectByPrimaryKey(afterSaleOrder.getOrderId());
            String disOrder = JSON.toJSONString(info);
            //通知分消对订单分消信息进行结算
            rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_ORDER_CALCULATE_QUEUE, disOrder);
        }
    }


    private Boolean checkAllReturn(String spuOrderId) {
        OrderSpu spu = orderSpuDao.selectByPrimaryKey(spuOrderId);
        List<AfterSaleOrder> afterSaleOrders = afterSaleOrderDao.queryOrderSpuAfterSale(spuOrderId);
        if (!CollectionUtils.isEmpty(afterSaleOrders)) {
            Integer sum = afterSaleOrders.stream().filter(o -> o.getAfterSaleType().equals(OrderEnum.AfterType.RETURN.getCode())
                    && o.getAfterSaleStatus().equals(OrderEnum.AfterStatus.REFUNDED.getCode())).mapToInt(AfterSaleOrder::getSkuQty).sum();
            if (sum != null && spu.getSkuQty().equals(sum)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 更新状态
     *
     * @return
     */
    public void updateStatus(String afterId, Integer status) {
        ParamException.isBlank(afterId, "售后单号为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(afterId);
        ParamException.isNull(afterSaleOrder);
        AfterSaleOrder afterSaleOrder1 = new AfterSaleOrder();
        afterSaleOrder1.setId(afterId);
        afterSaleOrder1.setAfterSaleStatus(status);
        afterSaleOrderDao.updateByPrimaryKeySelective(afterSaleOrder1);
    }


    /**
     * 订单过期关闭
     *
     * @return
     */
    public void orderAutoClosed() {
        List<AfterSaleOrder> afterSaleOrders = afterSaleOrderDao.selectExpirationOrder();
        afterSaleOrders.forEach(AfterSaleOrder -> {
            //关闭订单
            afterSaleOrderDao.afterSaleOrderClosed(AfterSaleOrder.getId());
            //更新零售订单状态
/*            OrderInfo orderInfo=new OrderInfo();
            orderInfo.setId(AfterSaleOrder.getOrderId());
            orderInfo.setIsAfterSale(2);
            orderInfoDao.updateByPrimaryKeySelective(orderInfo);*/


            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(AfterSaleOrder.getSpuOrderId());
            orderSpu.setIsAfterSale(2);
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);

            //更新快照售后信息
            upSkuSnapshoot(AfterSaleOrder.getOrderId());
        });
    }

    /**
     * 退款成功
     */
    @Transactional(rollbackFor = Exception.class)
    public void completeRefund(OrderRefundsVo orderRefundsVo) {
        ParamException.isBlank(orderRefundsVo.getBizRefundsNo(), "售后单号为空");
        AfterSaleOrder afterSaleOrder = afterSaleOrderDao.selectByPrimaryKey(orderRefundsVo.getBizRefundsNo());
        ParamException.isNull(afterSaleOrder);
        //只处理支付成功的订单
        //  ParamException.isFalse(StatusEnum.SUCCEED.getCode().equals(orderRefundsVo.getStatus()));
/*        ParamException.isTrue(afterSaleOrder.getAfterSaleStatus()!=OrderEnum.AfterStatus.REFUNDING.getCode(),
                "当前状态"+OrderEnum.AfterStatus.getValueByCode(afterSaleOrder.getAfterSaleStatus())+"不可以完成退款");*/

        //只处理成功或者失败的请求
        if (OrderEnum.PayStatus.SUCCEED.getCode().equals(orderRefundsVo.getStatus())) {
            updateStatus(afterSaleOrder.getId(), OrderEnum.AfterStatus.REFUNDED.getCode());
            //更新零售订单状态
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setId(afterSaleOrder.getOrderId());
            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(afterSaleOrder.getSpuOrderId());
            //仅退款
            if (afterSaleOrder.getAfterSaleType().equals(OrderEnum.AfterType.REFUND.getCode())) {
                orderSpu.setIsAfterSale(OrderEnum.OrderStatus.REFUND.getCode());
                orderSpu.setAfterSaleStatus(OrderEnum.OrderStatus.REFUND.getCode());
            } else {
                //校验是否已经退款所有
                Boolean bool = checkAllReturn(afterSaleOrder.getSpuOrderId());
                if (bool) {
                    orderSpu.setIsAfterSale(OrderEnum.OrderStatus.REFUND.getCode());
                    orderSpu.setAfterSaleStatus(OrderEnum.OrderStatus.REFUND.getCode());
                } else {
                    orderSpu.setIsAfterSale(OrderEnum.OrderStatus.SEND.getCode());
                }
            }
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);

            //更新售后状态快照
            upSkuSnapshoot(afterSaleOrder.getOrderId());

            //仅退款
            if (OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType())) {
                OrderSpu spu = new OrderSpu();
                spu.setOrderId(afterSaleOrder.getOrderId());
                List<OrderSpu> spuList = orderSpuDao.select(spu);
                List<OrderSpu> list = spuList.stream().filter(o -> o.getIsAfterSale() == null || o.getIsAfterSale() != 6).collect(Collectors.toList());
                if (list == null || list.size() == 0) {
                    orderInfo.setStatus(OrderEnum.OrderStatus.REFUND.getCode());
                }
                //校验订单发货状态
                Integer check = checkOrderDelivery(afterSaleOrder.getOrderId());
                if (check == OrderEnum.OrderStatus.SEND.getCode()) {
                    orderInfo.setStatus(OrderEnum.OrderStatus.SEND.getCode());
                }
            }
            orderInfo.setIsAfterSale(OrderEnum.OrderStatus.SEND.getCode());
            orderInfoDao.updateByPrimaryKeySelective(orderInfo);
            //更新佣金单状态
            walletApi.finishOrderRefund(afterSaleOrder.getId());

            //通知分消对订单分消信息进行结算
            if (OrderEnum.OrderStatus.REFUND.getCode().equals(orderInfo.getStatus())) {
                OrderInfo info = orderInfoDao.selectByPrimaryKey(afterSaleOrder.getOrderId());
                String disOrder = JSON.toJSONString(info);
                rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_ORDER_CALCULATE_QUEUE, disOrder);
            }
        }
        if (OrderEnum.PayStatus.FILL.getCode().equals(orderRefundsVo.getStatus())) {
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setId(afterSaleOrder.getOrderId());
            OrderSpu orderSpu = new OrderSpu();
            orderSpu.setId(afterSaleOrder.getSpuOrderId());
            orderSpu.setIsAfterSale(OrderEnum.OrderStatus.PAYED.getCode());
            updateStatus(afterSaleOrder.getId(), OrderEnum.AfterStatus.REFUNDFAIL.getCode());
/*            if (OrderEnum.AfterType.REFUND.getCode().equals(afterSaleOrder.getAfterSaleType())){
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.APPLY.getCode());
            }else {
                updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.RECEIVED.getCode());
            }*/
            orderSpuDao.updateByPrimaryKeySelective(orderSpu);

            //更新售后状态快照
            upSkuSnapshoot(afterSaleOrder.getOrderId());
            walletApi.cancleOrderRefund(afterSaleOrder.getId());
        }

//        updateStatus(afterSaleOrder.getId(),OrderEnum.AfterStatus.REFUNDED.getCode());
//        //仅退款
///*        if (afterSaleOrder.getAfterSaleType()==OrderEnum.AfterType.REFUND.getCode()){
//        }*/
//        //更新零售订单状态
//        OrderInfo orderInfo=new OrderInfo();
//        orderInfo.setId(afterSaleOrder.getOrderId());
//        orderInfo.setStatus(6);
//        orderInfo.setIsAfterSale(2);
//        orderInfoDao.updateByPrimaryKeySelective(orderInfo);

    }

    /**
     * 检查退款状态
     * 是否可以售后检查: 1.当前有售后未结束不能售后 2.已经退了所有金额所以不能售后
     * 3.已经退了所有数量所以不能售后 4.已过期不能售后 5可以售后 6订单未支付,不能退款
     * 7.只有官方的订单可以售后
     */
    public AfterSaleOrderCheckVo checkAfterSale(String spuOrderId) {
        AfterSaleOrderCheckVo afterSaleOrderCheckVo = new AfterSaleOrderCheckVo();
        afterSaleOrderCheckVo.setSpuOrderId(spuOrderId);
        afterSaleOrderCheckVo.setAfterSaleCheck(5);

        OrderSpu spu = orderSpuDao.selectByPrimaryKey(spuOrderId);
        ParamException.isTrue(spu == null, "订单[" + spuOrderId + "]不存在");

        afterSaleOrderCheckVo.setAllowAfterAmounts(spu.getRealPrice().multiply(new BigDecimal(spu.getSkuQty())));
        afterSaleOrderCheckVo.setAllowAfterQty(spu.getSkuQty());

        //判断是否已经过售后保质期
        AfterSaleOrder afterSaleOrder = new AfterSaleOrder();
        afterSaleOrder.setSpuOrderId(spu.getId());
        List<AfterSaleOrder> afterSaleOrderList = afterSaleOrderDao.select(afterSaleOrder);
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(spu.getOrderId());
        OrderInfo orderInfo2 = orderInfoDao.selectOne(orderInfo);
        //只有官方的订单可以售后
        ShopVo vo = shopApi.getDefaultShopForApi().getResult();
        if (vo != null && !vo.getId().equals(orderInfo2.getShopId())) {
            afterSaleOrderCheckVo.setAfterSaleCheck(7);
            return afterSaleOrderCheckVo;
        }
        //校验是否过保修期
        if (orderInfo2.getRepairTime() != null && orderInfo2.getRepairTime().compareTo(Instant.now()) < 0) {
            afterSaleOrderCheckVo.setAfterSaleCheck(4);
            return afterSaleOrderCheckVo;
        }

        //校验是否未付款
        if (orderInfo2.getStatus() == 0) {
            afterSaleOrderCheckVo.setAfterSaleCheck(6);
            return afterSaleOrderCheckVo;
        }

        if (afterSaleOrderList != null && afterSaleOrderList.size() != 0) {
            //校验是否有在进行的售后
            for (AfterSaleOrder o : afterSaleOrderList) {
                if (o.getAfterSaleStatus() >= 1 && o.getAfterSaleStatus() <= 5) {
                    afterSaleOrderCheckVo.setAfterSaleCheck(1);
                    return afterSaleOrderCheckVo;
                }
            }

            //已退款金额
            BigDecimal amount = afterSaleOrderList.stream().filter(o -> o.getAfterSaleStatus() == 6 && o.getAfterSaleAmount() != null).map(o -> o.getAfterSaleAmount())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //已退款数量
            int qty = afterSaleOrderList.stream().filter(o -> o.getAfterSaleStatus() == 6 && o.getSkuQty() != null)
                    .mapToInt(AfterSaleOrder::getSkuQty).sum();


            //校验已经退了所有金额
            if (amount.compareTo(spu.getRealPrice().multiply(new BigDecimal(spu.getSkuQty()))) >= 0) {
                afterSaleOrderCheckVo.setAfterSaleCheck(2);
                return afterSaleOrderCheckVo;
            }

            //校验已经退了所有数量
            if (qty > spu.getSkuQty()) {
                afterSaleOrderCheckVo.setAfterSaleCheck(3);
                return afterSaleOrderCheckVo;
            }

            afterSaleOrderCheckVo.setAllowAfterAmounts(spu.getRealPrice().multiply(new BigDecimal(spu.getSkuQty())).subtract(amount));
            afterSaleOrderCheckVo.setAllowAfterQty(spu.getSkuQty() - qty);
        }

        return afterSaleOrderCheckVo;
    }


    /**
     * 检测订单发货状态,如果2件商品按商品发货,如果1件商品已经发货,另1件进行了退款,订单更新成已发货
     *
     * @param orderId
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer checkOrderDelivery(String orderId) {
        ParamException.isBlank(orderId, "订单id为空");
        OrderListApiBo orderListApiBo = new OrderListApiBo();
        orderListApiBo.setOrderId(orderId);
        List<OrderAddr> orderAddr = orderAddrDao.queryOrderAddrs(orderListApiBo);
        ParamException.isTrue(orderAddr == null || orderAddr.size() == 0, "订单不存在或者未付款");

        OrderSpu spu = new OrderSpu();
        spu.setOrderId(orderId);
        //未售后单据
        //List<OrderSpu> orderSpus = orderSpuDao.select(spu).stream().filter(o->o.getIsAfterSale()==null||o.getIsAfterSale()==0).collect(Collectors.toList());
        //已售后单据
        List<OrderSpu> orderSpus2 = orderSpuDao.select(spu).stream().filter(o -> o.getIsAfterSale() != null && o.getIsAfterSale() != 0).collect(Collectors.toList());

        //查询未发货订单
        List<OrderAddr> list = orderAddr.stream()
                .filter(o -> o.getType() == OrderEnum.AddrOrderStatus.UN_SEND.getCode()).collect(Collectors.toList());

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderAddr.get(0).getOrderId());
        orderInfo.setStatus(OrderEnum.OrderStatus.SEND.getCode());

        if (list != null && list.size() != 0) {
            Integer num = 0;
            for (OrderAddr addr : list) {
                for (OrderSpu orderSpu : orderSpus2) {
                    if (orderSpu.getSkuId().equals(addr.getSkuId())) {
                        num = num + 1;
                    }
                }
            }
            if (num == list.size() && list.size() != orderAddr.size()) {
                return OrderEnum.OrderStatus.SEND.getCode();
            }
        }

        return OrderEnum.OrderStatus.PAYED.getCode();
    }

}
